home *** CD-ROM | disk | FTP | other *** search
/ Best of Shareware / Best of PC Windows Shareware 1.0 - Wayzata Technology (7111) (1993).iso / mac / DOS / TELECOMM / PCCP047 / XMODEMR.C < prev    next >
Text File  |  1992-05-26  |  4KB  |  196 lines

  1. /*    Copyright (C) 1992 Peter Edward Cann, all rights reserved.
  2.  *    MicroSoft QuickC: >qcl term.c graphics.lib
  3.  */
  4.  
  5. #include<stdio.h>
  6. #include<bios.h>
  7. #include<dos.h>
  8. #include<fcntl.h>
  9. #include<sys\types.h>
  10. #include<sys\stat.h>
  11. #include<signal.h>
  12. #include"port.h"
  13.  
  14. #define NAK 21
  15. #define ACK 6
  16. #define SOH 1
  17. #define EOT 4
  18. #define CAN 24
  19.  
  20. sendchar(c)
  21.     unsigned char c;
  22.     {
  23.     while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)));
  24.     outp(basereg, c);
  25.     }
  26.  
  27. int follow;
  28.  
  29. int rcharto(ticks)
  30.     int ticks;
  31.     {
  32.     long tstamp, tstamp1, dayofticksp;
  33.     int c;
  34.     _bios_timeofday(_TIME_GETCLOCK, &tstamp);
  35.     dayofticksp=0;
  36.     while(1)
  37.         {
  38.         if(_bios_timeofday(_TIME_GETCLOCK, &tstamp1))
  39.             dayofticksp+=20*60*60*24;
  40.         if(tstamp1+dayofticksp-tstamp>ticks)
  41.             return(-1); /* NOTE: This is an INT!!! */
  42.         if(follow!=index)
  43.             {
  44.             c=buf[follow++];
  45.             follow=follow%TBUFSIZ;
  46.             return(c);
  47.             }
  48.         }
  49.     }
  50.  
  51.  
  52. unsigned char block[128];
  53.  
  54. rblock()
  55.     {
  56.     int i, blockn, invblockn, rchecksum, checksum;
  57.     checksum=0;
  58.     if((blockn=rcharto(20))==-1)
  59.         return(-1);
  60.     printf("Block %d: ", blockn);
  61.     if((invblockn=rcharto(20))==-1)
  62.         return(-1);
  63.     for(i=0;i<128;++i)
  64.         {
  65.         if((block[i]=rcharto(20))==-1)
  66.             return(-1);
  67.         checksum+=block[i];
  68.         checksum&=0xff;
  69.         }
  70.     if((rchecksum=rcharto(20))==-1)
  71.         return(-1);
  72.     if(((invblockn^0xff)&0xff)!=blockn)
  73.         {
  74.         printf("Bad complement block number.\n");
  75.         return(-1);
  76.         }
  77.     if(checksum!=rchecksum)
  78.         {
  79.         printf("Checksum mismatch. Here=%02x There=%02x.\n", checksum, rchecksum);
  80.         return(-1);
  81.         }
  82.     return(blockn);
  83.     }
  84.  
  85. quit()
  86.     {
  87.     cleanup(0);
  88.     exit(99);
  89.     }
  90.  
  91. main(argc, argv)
  92.     int argc;
  93.     char **argv;
  94.     {
  95.     int i, j, outfd, ok, c;
  96.     long nbytes;
  97.     unsigned char blocknum;
  98.     index=follow=0;
  99.     printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
  100.     printf("xmodem checksum receive of %s.\n", argv[4]);
  101.     if(argc!=5)
  102.         {
  103.         printf("USAGE: xmodemr <comnum> <bps> <stopbits> <file pathname>\n");
  104.         exit(1);
  105.         }
  106.     if((outfd=open(argv[4], O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, S_IWRITE))==-1)
  107.         {
  108.         printf("Error opening file %s.\n", argv[4]);
  109.         exit(2);
  110.         }
  111.     comnum=atoi(argv[1])-1;
  112.     speed=atoi(argv[2]);
  113.     databits='8';
  114.     parity='n';
  115.     stopbits=argv[3][0];
  116.     setport();
  117.     signal(SIGINT, quit);
  118.     readset();
  119.     setup();
  120.     ok=nbytes=0;
  121.     for(i=0;i<10;++i)
  122.         {
  123.         sendchar(NAK);
  124.         c=rcharto(200);
  125.         if(c==SOH)
  126.             {
  127.             ok=1;
  128.             break;
  129.             }
  130.         }
  131.     if(!ok)
  132.         {
  133.         printf("No SOH after 10 10-second-spaced NAKs.\n");
  134.         cleanup(0);
  135.         exit(10);
  136.         }
  137.     blocknum=1;
  138.     for(i=0;i<10;++i)
  139.         {
  140.         printf("\nSeeking block %d: ", blocknum);
  141.         if((c=rblock())==blocknum)
  142.             {
  143.             i=0;
  144.             if(write(outfd, block, 128)!=128)
  145.                 {
  146.                 printf("Write error.\n");
  147.                 cleanup(0);
  148.                 exit(13);
  149.                 }
  150.             nbytes+=128;
  151.             printf("Successful. Bytes so far: %ld", nbytes);
  152.             blocknum=(blocknum+1)&0xff;
  153.             sendchar(ACK);
  154.             }
  155.         else
  156.             if(c==-1)
  157.                 {
  158.                 while(rcharto(20)!=-1);
  159.                 sendchar(NAK);
  160.                 }
  161.             else if(c<blocknum)
  162.                 sendchar(ACK);
  163.             else
  164.                 {
  165.                 printf("\nSender skipped a block; cancelling transfer.\n");
  166.                 for(j=0;j<10;++j)
  167.                     sendchar(CAN);
  168.                 cleanup(0);
  169.                 exit(14);
  170.                 }
  171.         do
  172.             c=rcharto(200);
  173.         while((c!=EOT)&&(c!=SOH)&&(c!=CAN)&&(c!=-1));
  174.         if(c==EOT)
  175.             {
  176.             sendchar(ACK);
  177.             printf("\nTransfer successful.\n");
  178.             close(outfd);
  179.             cleanup(0);
  180.             exit(0);
  181.             }
  182.         if(c!=SOH)
  183.             {
  184.             if(c==-1)
  185.                 printf("Timeout waiting for SOH or EOT.\n");
  186.             else
  187.                 printf("Spurrious character hex %02x; SOH or EOT expected.\n", c);
  188.             cleanup(0);
  189.             exit(11);
  190.             }
  191.         }
  192.     printf("Retry limit exceeded.\n");
  193.     cleanup(0);
  194.     exit(12);
  195.     }
  196.